package com.sun.huazhi.aitaskservice.controller;

import com.sun.huazhi.aitaskservice.DTO.request.AudioTranscriptRequest;
import com.sun.huazhi.aitaskservice.DTO.request.SpeechQueryRequest;
import com.sun.huazhi.aitaskservice.DTO.request.TextToSpeechRequest;
import com.sun.huazhi.aitaskservice.DTO.response.*;
import com.sun.huazhi.aitaskservice.common.config.PythonApiProperties;
import com.sun.huazhi.aitaskservice.common.resilience.ResilientServiceExecutor;
import com.sun.huazhi.aitaskservice.common.utils.FileTypeValidator;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import java.io.IOException;
import java.util.Base64;
import java.util.Map;

@Slf4j
@RestController
@RequestMapping("/api/speech")
@Tag(name = "语音交互", description = "提供语音识别、语音合成和相关问答功能")
public class SpeechController {

    @Autowired
    @Qualifier("pythonApiProperties")
    private PythonApiProperties apiProps;

    @Autowired
    private WebClient webClient;

    @Autowired
    private ResilientServiceExecutor resilientExecutor;

    @PostMapping("/speech-to-text")
    @Operation(summary = "语音识别（JSON）",
            description = "将语音转换为文本，支持多种方言")
    public Mono<ResponseEntity<SpeechRecognitionResponse>> transcribeAudio(@RequestParam("audio") MultipartFile audioFile) throws IOException {
        if (!FileTypeValidator.isAllowedContentType(audioFile.getContentType())) {
            SpeechRecognitionResponse response = new SpeechRecognitionResponse();
            response.setTranscription("不支持的文件类型");
            return Mono.just(ResponseEntity.badRequest().body(response));
        }

        String url = apiProps.getUrl() + "/speech-to-text";
        byte[] audioBytes = audioFile.getBytes();
        String base64Audio = Base64.getEncoder().encodeToString(audioBytes);

        AudioTranscriptRequest request = new AudioTranscriptRequest();
        request.setAudioBase64(base64Audio);
        request.setDialect("mandarin");

        return resilientExecutor.execute(() ->
                webClient.post()
                        .uri(url)
                        .contentType(MediaType.APPLICATION_JSON)
                        .bodyValue(request)
                        .retrieve()
                        .bodyToMono(SpeechRecognitionResponse.class)
                        .map(ResponseEntity::ok));
    }

    @PostMapping(value = "/recognize-form", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    @Operation(summary = "语音识别（表单）",
            description = "表单方式提交音频进行语音识别")
    public Mono<ResponseEntity<SpeechRecognitionResponse>> speechForm(@RequestPart("audio") MultipartFile audio,
                                                   @RequestPart("dialect") String dialect) throws IOException {
        if (!FileTypeValidator.isAllowedContentType(audio.getContentType())) {
            SpeechRecognitionResponse response = new SpeechRecognitionResponse();
            response.setTranscription("不支持的文件类型");
            return Mono.just(ResponseEntity.badRequest().body(response));
        }

        return webClient.post()
                .uri(apiProps.getUrl() + "/speech-to-text-form")
                .contentType(MediaType.MULTIPART_FORM_DATA)
                .body(BodyInserters.fromMultipartData("audio", audio)
                        .with("dialect", dialect))
                .retrieve()
                .bodyToMono(SpeechRecognitionResponse.class)
                .map(ResponseEntity::ok);
    }

    @PostMapping("/text-to-speech")
    @Operation(summary = "语音合成",
            description = "将文本转换为语音，支持多种音色")
    public Mono<ResponseEntity<TextToSpeechResponse>> textToSpeech(@RequestBody TextToSpeechRequest request) {
        return webClient.post()
                .uri(apiProps.getUrl() + "/text-to-speech")
                .contentType(MediaType.APPLICATION_JSON)
                .bodyValue(request)
                .retrieve()
                .bodyToMono(byte[].class)
                .map(audioBytes -> {
                    TextToSpeechResponse response = new TextToSpeechResponse();
                    response.setAudio_base64(Base64.getEncoder().encodeToString(audioBytes));
                    response.setFormat("wav");
                    response.setVoice_id(request.getVoiceId());
                    return ResponseEntity.ok(response);
                });
    }

    @PostMapping("/query")
    @Operation(summary = "语音智能问答",
            description = "结合语音识别、问答处理和语音合成的完整流程")
    public Mono<ResponseEntity<SpeechQueryResponse>> speechQuery(@RequestBody SpeechQueryRequest request) {
        return webClient.post()
                .uri(apiProps.getUrl() + "/speech-query")
                .contentType(MediaType.APPLICATION_JSON)
                .bodyValue(request)
                .retrieve()
                .bodyToMono(SpeechQueryResponse.class)
                .map(ResponseEntity::ok);
    }


    //TODO : Python未实现 等待接口
//    @PostMapping("/detect-dialect")
//    public Mono<ResponseEntity<DialectDetectionResponse>> detectDialect(
//            @RequestParam("audio") MultipartFile audioFile) throws IOException {
//
//    }
}
